(*DONT_TOUCH = "TRUE"*)
module ParticleCounter #(
    parameter THRESHOLD_HIGH = 16'd625,   // 连续高于此值计数+1
    parameter THRESHOLD_LOW = 16'd563,     // 连续低于此值等待重新计数
    parameter COUNT_HIGH_CYCLES = 500,        // 连续高于阈值的最小周期数
    parameter COUNT_LOW_CYCLES = 500,          // 连续低于阈值的最小周期数
    parameter COUNT_LOW_INTERVAL = 250000     // WAIT_LOW状态每持续该周期数，count加1 2ms
)(
    input wire clk,              // 时钟信号
    input wire rst_n,            // 异步复位信号，低电平有效
    input wire start,            // 开始计数信号
    input wire clear,            // 清零信号
    input wire [15:0] adc_data,  // 16位ADC采样数据
    output reg [31:0] count     // 颗粒计数输出
);

    // 状态定义
    
    parameter IDLE = 2'b00;         // 空闲状态
    parameter WAIT_HIGH = 2'b01;   // 等待信号高于阈值
    parameter WAIT_LOW = 2'b10;     // 等待信号低于阈值
    

    reg [1:0] current_state, next_state;  // 当前状态和下一状态

    // 连续计数寄存器
    reg [15:0] high_count;
    reg [15:0] low_count;
    reg [15:0] low_interval_count; // 新增计数器

    reg counting_flag;     // 当前是否在计数的标志

    // 状态寄存器
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            current_state <= IDLE;
        else
            current_state <= next_state;
    end

    // 状态转移逻辑
    always @(*) begin
        // 默认值
        next_state = current_state;
        case (current_state)
            IDLE: begin
                if (start)
                    next_state = WAIT_HIGH;
            end
            WAIT_HIGH: begin
                if (high_count >= COUNT_HIGH_CYCLES - 1)
                    next_state = WAIT_LOW;
            end
            WAIT_LOW: begin
                if (low_count >= COUNT_LOW_CYCLES - 1)
                    next_state = WAIT_HIGH;
            end
        endcase
    end

    // 输出逻辑
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            count <= 32'b0;
            high_count <= 16'b0;
            low_count <= 16'b0;
            low_interval_count <= 16'b0;
            counting_flag <= 1'b0;
        end else if (clear) begin
            count <= 32'b0;
        end else begin
            case (current_state)
                IDLE: begin
                    if (start) begin
                        count <= 32'b0;
                        high_count <= 16'b0;
                        low_count <= 16'b0;
                        low_interval_count <= 16'b0;
                        counting_flag <= 1'b0;
                    end
                end
                WAIT_HIGH: begin
                    if (adc_data > THRESHOLD_HIGH && adc_data[15] == 0) begin
                        high_count <= high_count + 1;
                        if (high_count == COUNT_HIGH_CYCLES - 1 && counting_flag == 1'b0) begin
                            count <= count + 1;
                            counting_flag <= 1'b1;
                            high_count <= 16'b0;  // 重置高计数
                        end
                    end else begin
                        high_count <= 16'b0;  // 未达到连续条件时重置
                    end
                end
                WAIT_LOW: begin
                    if (adc_data <= THRESHOLD_LOW || adc_data[15] == 1) begin //adc小于最低阈值
                        low_count <= low_count + 1;
                        low_interval_count <= 0;
                        if (low_count == COUNT_LOW_CYCLES - 1 && counting_flag == 1'b1) begin
                            counting_flag <= 1'b0;
                            low_count <= 16'b0;  // 重置低计数
                        end
                    end else begin //adc大于最低阈值
                        low_count <= 16'b0;  // 未达到连续条件时重置
                        //做时间累计做粘连处理
                        low_interval_count <= low_interval_count + 1;
                        // 达到间隔周期数时增加计数
                        if (low_interval_count == COUNT_LOW_INTERVAL - 1) begin
                            count <= count + 1;
                            low_interval_count <= 0;
                        end
                    end
                end
            endcase
        end
    end
endmodule
